package com.shelly.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: Shelly
 * @create: 2023-01-11 23:44:07
 * @describe:
 * 1、宝宝本来在卧室睡觉【没哭】
 * 2、现在醒了，醒了就会哭
 * 3、触发事件WakeUpEvent，给爸爸妈妈这两个观察者发现
 * 4、如果在卧室，就给爸爸处理，爸爸喂奶，宝宝就不哭
 * 5、爸爸妈妈可以处理其他事
 *
 * 涉及观察者的原理
 * 1、加入事件类：可以传入观察者接口，把观察者和被观察者分离开；
 * 2、事件类中可以带上属性和事件源对象：传给观察者，作为判断标准
 * 3、事件也可以形成继承体系，因为观察者可以监听不同的事件源对象
 */
public class ObserverPatt {
    public static void main(String[] args) {

    }
}
// 被观察者
class Child{
    private boolean cry = false;
    private List<Observer> filters = new ArrayList<>();
    {
        filters.add(new Dad());
        filters.add(new Mom());
    }

    public void wakeup(){
        cry = true;
        System.out.println("宝宝睡醒后哭了");
        WakeUpEvent event = new WakeUpEvent("卧室",this);
        for (Observer o:filters){
            o.actionOnWakeUp(event);// 可以根据具体事件，触发对应的观察者
        }
    }
    public boolean isCry(){
        return cry;
    }
    public void noCry(){
        cry = false;
    }
}
// 事件也可以形成继承体系
abstract class Event<T>{
    abstract T getSource();
}
class WakeUpEvent extends Event<Child>{
    private String location;
    private Child source;

    public WakeUpEvent(String location,Child child){
        this.location = location;
        this.source = child;
    }
    public String getLocation(){
        return this.location;
    }
    @Override
    public Child getSource(){
        return source;
    }
}
// 观察者不能和事件源绑定
interface Observer{
    public void actionOnWakeUp(WakeUpEvent event);
}
class Mom implements Observer{
    public void hug(){
        System.out.println("Mom hug！");
    }
    // 妈妈抱宝宝不哭
    @Override
    public void actionOnWakeUp(WakeUpEvent event) {
        if ("客厅".equals(event.getLocation())){
            this.hug();
            Child child = event.getSource();
            child.noCry();
        }
    }
}
class Dad implements Observer{
    public void feed(){
        System.out.println("Dad feed！");
    }
    // 喂了奶以后宝宝不哭
    @Override
    public void actionOnWakeUp(WakeUpEvent event) {
        if ("卧室".equals(event.getLocation())) {// 不同的情境下，根据被观察者的状态会给不同的观察者处理
            this.feed();
            Child child = event.getSource();
            child.noCry();
        }
    }
}

class Test{
    public static void main(String[] args) {
        Child child = new Child();
        child.wakeup();
        System.out.println("宝宝现在还哭吗？"+ (child.isCry()?"哭了":"没哭"));
    }
}